//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#include <core.h>
#include <_hal.h>

uint_t g_uLoopCountPerMicrosecond = 0;

STATIC DECL_CODEINIT void CDECL TimerRoutine(void *pvParameter)
{
    assert(pvParameter);

    *(bool_t *)pvParameter = FALSE;
}

const uint_t c_uMeasureTicks = 10;

EXTERN DECL_CODEINIT void InitDelayParameter()
{
    volatile bool_t bContinue = TRUE;

    DzTimer timer(c_uMeasureTicks, TimerRoutine, (void *)&bContinue);

    timer.Start();

    volatile uint_t u = 0;
    volatile uint_t uCount = 0xffffffff;

    while (bContinue && u < uCount) {
        u++;
    }

    g_uLoopCountPerMicrosecond =
        u / DzTicksToMilliseconds(c_uMeasureTicks) / 1000;

    if (0 == g_uLoopCountPerMicrosecond) g_uLoopCountPerMicrosecond = 1;

#if (_TEST_TYPE == 3)     /* Test for schedule performance */ \
    || (_TEST_TYPE == 21) /* Test for x86 system clock interruption response performance */ \
    || (_TEST_TYPE == 22) /* Test for x86 disable and restore preemption performance */ \
    || (_TEST_TYPE == 23) /* Test for x86 disable and restore interruption performance */

    kprintf("g_uLoopCountPerMicrosecond = %d\n", g_uLoopCountPerMicrosecond);
#endif // _TEST_TYPE == 3 || ...
}

EXTERN void DzDelay(Microsecond32 microseconds)
{
    assert(0 != g_uLoopCountPerMicrosecond);

    volatile bool_t bContinue = TRUE;

    volatile uint_t u;
    volatile uint_t uCount;
    register uint_t uCurrentDelayMicroseconds;

    do {
        uCurrentDelayMicroseconds = UINT_MAX / g_uLoopCountPerMicrosecond;
        if (microseconds < (Int32)uCurrentDelayMicroseconds) {
            uCurrentDelayMicroseconds = microseconds;
        }

        u = 0;
        uCount = g_uLoopCountPerMicrosecond * uCurrentDelayMicroseconds;

        while (bContinue && u < uCount) {
            u++;
        }

        microseconds -= uCurrentDelayMicroseconds;
    } while (0 < microseconds);
}
